#include <iostream>
using namespace std;

/*
    虚继承解决环状继承引发的两个问题
    1.虚继承的语法
    class 子类：virtual public 父类    //virtual表示虚继承
    2.虚继承的底层原理-- 》 虚继承是如何解决菱形继承的问题的
    1.子类虚继承了父类，子类的地址空间里面会多出一个指针
    2.这个指针用来指向虚基类的首地址的
    3.虚基类：Animal就是虚基类


    第一步：先构建猫科，猫科地址空间有个指针，C++通过这个指针找到虚基类
            Anima1调用Animal的无参构造，在构建猫科自己
    第二步：再构建哺乳，哺乳地址空间有个指针，C++通过这个指针找到虚基类，会跟猫科动物的那个指针进行比较，
            发现两个指针指向的是同一个虚基类，因此后面就不再重复创建Animal了
    
    if (哺乳.指针==猫科.指针)
      不再重复新建Animal
    else
      才会去创建别的虚基类
*/

class Animal
{
public:
    Animal()
    {
        cout << "Animal" << endl;
    }
    void eat()
    {
        cout << "Animal eat" << endl;
    }
};

class Catamount : virtual public Animal
{
public:
    Catamount()
    {
        cout << "Catamount" << endl;
    }
    void eat()
    {
        cout << "catamount eat" << endl;
    }
};

class Mammal : virtual public Animal
{
public:
    Mammal()
    {
        cout << "Mammal" << endl;
    }
    void eat()
    {
        cout << "mammal eat" << endl;
    }
};

class Cat : public Catamount, public Mammal
{
public:
    Cat()
    {
        cout << "Cat" << endl;
    }
    void eat()
    {
        cout << "cat eat" << endl;
    }
};

int main()
{
    Cat c;
    c.eat();

    c.Animal::eat(); // 虚继承解决二义性问题
    return 0;
} 